package joymouse;

import java.awt.event.InputEvent;
import joymouse.logger.Logger;
import net.java.games.input.Component;
import net.java.games.input.Controller;

/**
 * Controller for the keys on the mouse (which are the same in both relative and
 * absolute mode). The buttons used are hard coded for the Logitech Attack 3
 * joystick which I use for testing. The intended controls are:
 * <ul>
 * <li>Trigger - left click</li>
 * <li>Top right button - right click</li>
 * <li>Top upper button - scroll up</li>
 * <li>Top lower button - scroll up</li>
 * </ul>
 * These may vary if you use controllers other than the Attack 3.
 *
 *
 * @author Ben Wolsieffer
 */
public class KeyController extends DeviceController {
    // Components that are used for input

    private Component leftClick;
    private Component rightClick;
    private Component scrollUp;
    private Component scrollDown;
    // Stores whether the mouse buttons were aleady pressed
    private boolean leftDown = false;
    private boolean rightDown = false;
    // The last time the run() method was called, in order to time button
    // repeating
    private long lastTime;
    // The time to wait between repeating a key when a button is pressed.
    private static final int KEY_REPEAT_DELAY = 100;

    public KeyController(Controller cont) {
        super(cont);
        Component[] components = controller.getComponents();
        for (Component com : components) {
            Component.Identifier iden = com.getIdentifier();
            if ((iden == Component.Identifier.Button.TRIGGER // The trigger
                    || iden == Component.Identifier.Button._0) && !com.isAnalog()) { // or button 0, because on the Attack 3, 
                leftClick = com;                                                     // the trigger is not recognized as such
                Logger.getLogger().log("Left click assigned to " + com);
            } else if (iden == Component.Identifier.Button._4) { // Top right button on Logitech Attack 3
                rightClick = com;
                Logger.getLogger().log("Right click assigned to " + com);
            } else if (iden == Component.Identifier.Button._2) { // Top right button on Logitech Attack 3
                scrollUp = com;
                Logger.getLogger().log("Scroll up assigned to " + com);
            } else if (iden == Component.Identifier.Button._1) { // Top right button on Logitech Attack 3
                scrollDown = com;
                Logger.getLogger().log("Scroll down assigned to " + com);
            }
        }
        lastTime = System.currentTimeMillis();
    }

    @Override
    protected void run() {
        // Button pressed value is 1.0
        if (leftClick.getPollData() == 1.0 && !leftDown) {
            leftDown = true;
            robot.mousePress(InputEvent.BUTTON1_MASK);
        }
        if (leftClick.getPollData() == 0.0 && leftDown) {
            robot.mouseRelease(InputEvent.BUTTON1_MASK);
            leftDown = false;
        }
        if (rightClick.getPollData() == 1.0 && !rightDown) {
            rightDown = true;
            robot.mousePress(InputEvent.BUTTON3_MASK);
        }
        if (rightClick.getPollData() == 0.0 && rightDown) {
            robot.mouseRelease(InputEvent.BUTTON3_MASK);
            rightDown = false;
        }
        // Timing code that only scrolls every KEY_REPEAT_DELAY milliseconds
        // The same timer is used for both up and down scrolling, which should
        // possibly be changed
        long currTime = System.currentTimeMillis();
        long elapsedTime = currTime - lastTime;
        if (scrollDown.getPollData() == 1.0 && elapsedTime > KEY_REPEAT_DELAY) {
            robot.mouseWheel(1);
            lastTime = currTime;
        }
        if (scrollUp.getPollData() == 1.0 && elapsedTime > KEY_REPEAT_DELAY) {
            robot.mouseWheel(-1);
            lastTime = currTime;
        }
    }
}
